<?php
namespace System\Controller;
use Think\Controller;
use Think\Upload;
/**
 * 2023.03.15 huhaiqin
 * 上传请求
 */
class UploadController extends Controller{
    private $upload_config;

    function __construct(){
        parent::__construct();
        $this->upload_config = F('UPLOAD_CONFIG') ? F('UPLOAD_CONFIG') : C('UPLOAD_CONFIG'); //加载上传的配置文件
        // $this->upload_config = C('UPLOAD_CONFIG');
    }

    /**
     * 2023.03.17 huhaiqin
     * 图片上传的统一调用入口
     */
    public function img(){
        // 根据配置文件判断上传方式
        $uid = $_SESSION['loginUser']['id'] ? $_SESSION['loginUser']['id'] : $_REQUEST['uid'];
        if(!$uid){
            _apiReturn(0,'请先登录~');
        }
        switch($this->upload_config['CURRENT_METHOD']){
            case 'qiniu':
                $this->_qiniu_img($uid,'qiniu');
                break;
            case 'aliyun':
                $this->_aliyun_img($uid,'aliyun');
                break;
            default:
                $this->_local_img($uid,'local');
        }
    }

    /**
     * 2023.05.22
     * 图片删除接口
     */
    public function del(){
        $uid = $_SESSION['loginUser']['id'] ? $_SESSION['loginUser']['id'] : $_REQUEST['uid'];
        if(!$uid){
            _apiReturn(0,'请先登录~');
        }
        if(!$_REQUEST['id']){
            _apiReturn(0,'缺少文件ID~');
        }
        // 组成条件
        if($_SESSION['loginUser']['role'] == 'admin'){
            $map = ['id' => $_REQUEST['id']];
        }else{
            $map = [
                'id'  => $_REQUEST['id'],
                'uid' => $uid
            ];
        }
        $m = D('File');
        $check = $m->where($map)->find();
        if(!$check){
            _apiReturn(0,'文件不存在~');
        }
        if($check['ac'] == '' || $check['ac'] == 'local'){
            unlink('.'.$check['url']); // 删除文件
        }
        if($check['qiniu']){
            $config = $this->upload_config['PIC'];
            $qiniu = new \Think\Upload\Driver\Qiniu($this->upload_config['QINIU_CONFIG']);
            $qiniu->del($check['url']); // 远程删除
        }
        if($m->where($map)->delete()){
            _apiReturn(1,'success');
        }else{
            _apiReturn(0,'error');
        }

    }

    public function qiniu_uptoken(){
        Vendor('Qiniu.Config');
        Vendor('Qiniu.functions');
        vendor('Qiniu.Auth');
        $config = $this->upload_config['QINIU_CONFIG'];
        $accessKey = $config['accessKey'];
        $secretKey = $config['secretKey'];
        $auth = new \Qiniu\Auth($accessKey, $secretKey);
    
		$bucket = $config['bucket'];
        $upToken = $auth->uploadToken($bucket);
        $data['uptoken'] = $upToken;
        header('Content-Type:application/json; charset=utf-8');
        header("Access-Control-Allow-Origin: *");  //跨域请求
        echo '{"uptoken":"'.$upToken.'"}';
        die();
    }

    /**
     * 2023.03.17 huhaiqin
     * 私有函数，七牛云上传
     */
    public function _qiniu_img($uid = 0,$ac = 'qiniu'){
        if(!empty($_FILES)){
            $tmpfile = $_FILES['file'];
            if(!$tmpfile){
                $tmpfile = $_FILES['upfile'];
            }
            $config = $this->upload_config['PIC'];
            $qiniu = new \Think\Upload\Driver\Qiniu($this->upload_config['QINIU_CONFIG']);
            //检查文件名
            if (!$tmpfile['name']) {
                _apiReturn(0,"请选择文件。");
            }
            //检查文件大小
            if ($tmpfile['size'] > $config['maxSize']) {
                _apiReturn(0,"上传文件大小超过限制。");
            }
            //获得文件扩展名
            $temp_arr = explode(".", $tmpfile['name']);
            $file_ext = array_pop($temp_arr);
            $file_ext = trim($file_ext);
            $file_ext = strtolower($file_ext);
            //检查扩展名
            if (in_array($file_ext, $config['exts']) === false) {
                $this->_result_error($_REQUEST['dofor'],"只支持拓展名为".implode(",",$config['exts'])."文件");
            }
            $file['savename'] = uniqid().'.'.$file_ext;
            $file['tmp_name'] = $tmpfile['tmp_name'];
            if($qiniu->save($file)){
                $data = $this->_save_to_database('pic',$file['savename'],$qiniu->downLink($file['savename']),$tmpfile['size'],$tmpfile['name'],$uid,$ac);
                if($data){
                    $this->_result_success($data,$_REQUEST['dofor']); //返回数据
                }else{
                    $this->_result_error($_REQUEST['dofor'],'上传失败~');
                }
            }else{
                $this->_result_error($_REQUEST['dofor'],'检查七牛云配置');
            }
        }else{
            $this->_result_error($_REQUEST['dofor'],'选择文件~');
        }
    }


    /**
     * 2023.03.17 huhaiqin
     * 私有函数，阿里云上传
     */
    private function _aliyun_img($uid = 0,$ac = 'aliyun'){
        // 待实现
    }

    /**
     * 2023.03.17 huhaiqin
     * 私有函数，本地上传
     */
    private function _local_img($uid = 0,$ac = 'local'){
        $config = $this->upload_config['PIC'];
        $upload = new \Think\Upload($config);// 实例化上传类 
        if (!file_exists($config['rootPath'])) {  // 判断是否存在根目录文件夹       
            mkdir($config['rootPath'], 0777, true);
        }

        $url = $upload->upload();
        if($url){
            $url['url'] = $config['rootPathBase'].$url['file']['savepath'].$url['file']['savename'];

            // 如果上传的是图片，则需要研究一下是否需要对上传的图片进行压缩
            $imgObj = new \Think\Image();
            $imgObj->open("./".$url['url']);
            if($imgObj->width() > $config['maxWidth'] || $imgObj->height() > $config['maxHeight']){
                //宽度大于1920或高度大于1080，执行压缩
                $imgObj->thumb($config['maxWidth'], $config['maxHeight'])->save("./".$url['url']);//直接把缩略图覆盖原图
            }else{
                $imgObj->thumb($imgObj->width(), $imgObj->height())->save("./".$url['url']);//直接把缩略图覆盖原图
            }                

            $data = $this->_save_to_database('pic',$url['file']['savename'],$url['url'],$url['file']['size'],$url['file']['name'],$uid,$ac); //存储到数据库里面
            if($data){
                $this->_result_success($data,$_REQUEST['dofor']); //返回数据
            }else{
                $this->_result_error($_REQUEST['dofor'],'上传失败~');
            }
        }else{
            $this->_result_error($_REQUEST['dofor']);
        }
    }

    /**
     * huhaiqin 2023.03.17
     * 私有函数，统一返回格式
     * 返回结果
     * param $data 文件的数据格式
     * param $dofor 需要什么返回格式
     */
    private function _result_success($data = [], $dofor = 'default'){
        $resultData = [];
        switch ($dofor){
            case 'ueditor':
                $resultData = array(
                    "originalName" =>$data['title'] ,
                    "name" => $data['key'] ,
                    "url" => $data['url'] ,
                    "size" => $data['size'] ,
                    "type" =>  '.'.$url['file']['ext'],
                    "state" => "SUCCESS"
                );
                break;
            case 'tinymce':
                $resultData = array(
                    "originalName" =>$data['title'] ,
                    "name" => $data['key'] ,
                    "location" => $data['url'] ,
                    "size" => $data['size'] ,
                    "type" =>  '.'.$url['file']['ext'],
                    "state" => "SUCCESS"
                );
                break;
            case 'wangeditor':
                $resultData = array(
                    "errno" =>  0,
                    "data"  =>  [
                        "url"   => $data['url'],    //图片 src，必须      
                        "alt"   => $data['title'],  //图片文字描述，非必须
                        "href"  => '',              //图片的链接地址，非必须
                    ]      
                );
                break;
            default:
                $resultData = array(
                    "url"=>$data['url'],
                    "time"=>$data['create_time'],
                    "id"=>$data['id'],
                    "listorder" => 0,
                    "other"=>$_POST,
                    "title"=>$data['title'],
                    "redurl" => ""
                );
                _apiReturn(1,"success",$resultData);
        }
        echo json_encode($resultData,JSON_UNESCAPED_UNICODE);
        die();
    }

    /**
     * huhaiqin 2023.03.17
     * 异常时统一的返回格式
     */
    private function _result_error($dofor = 'default',$msg = 'fail to upload'){
        $resultData = [];
        switch ($dofor){
            case 'ueditor':
                $resultData = array(
                    "state" => $msg
                );
                break;
            case 'tinymce':
                $resultData = array(
                    "state" => $msg
                );
                break;
            case 'wangeditor':
                $resultData = array(
                    "errno" =>  1,
                    "message"  =>  $msg
                );
                break;
            default:
                _apiReturn(0,'上传失败~');
        }
        echo json_encode($resultData,JSON_UNESCAPED_UNICODE);
        die();
    }

    /**
     * huhaiqin 2023.03.17
     * 私有函数，存储到数据库
     */
    private function _save_to_database($type = 'pic',$key = '',$url = '',$size = 0,$title = '',$uid = 0,$ac = 'local'){
        $m = D('File');
        $data = [
            'fk_id'         => $_REQUEST['fk_id'],                                                              // 外键ID
            'fk_group'      => $_REQUEST['fk_group'],                                                           // 外键分组
            'uid'           => $uid,                                                                            // 上传者ID
            'ac'            => $ac,                                                                             // 记录上传方式
            'type'          => $type,                                                                           // 文件类型，pic,video,file
            'key'           => $key,                                                                            // 图片名称
            'url'           => $url,                                                                            // 图片存储地址
            'size'          => $size,                                                                           // 文件大小
            'title'         => $title,                                                                          // 原文件名
            'create_time'   => date('Y-m-d H:i:s')                                                              // 上传时间
        ];
        if(!$data['uid']){
            $this->_result_error($_REQUEST['dofor'],'请先登录~');
        }
        $data['id'] = $m->add($data);
        if($data['id']){
            return $data; //如果创建成功，则返回所有数据
        }else{
            return false; //创建失败，返回错误
        }
    }
}